﻿
using System;
using System.Collections.Generic;
using System.Text;
using Dapper;
using System.Linq;
using OddUserManager.Model;
using OddUserManager.Data.IRepositories;

namespace OddUserManager.Data.Repositories
{
    public class SiteRepository : DapperBaseRepository<Site, int>, ISiteRepository
    {

        public int GetSiteUserCount(List<int> ids)
        {
            int result = 0;
            using (var con = GetOpenConnection())
            {
                var sql = $"select count(Id) from OddUser where SiteId in({string.Join(",",ids)})"; 
                result = con.Query<int>(sql).FirstOrDefault();
            }
            return result;
        }

        public bool InsertOrUpdate(Site entity)
        {
            if (Get(entity.Id) == null)
            {
                return Insert(entity);
            }
            else {
                return Update(entity);
            }
        }


        public new bool Insert(Site entity)
        {
            bool isSuccess = false;
            var propertyContainer = ParseProperties(entity);
            var sql = $"insert into {typeof(Site).Name} ({string.Join(", ", propertyContainer.ValueNames)}) values (@{string.Join(", @", propertyContainer.ValueNames)})";
            using (var connection = GetOpenConnection())
            {
                
                var trans = connection.BeginTransaction();
                try {
                    //更改所有父级站点的边界值
                    var updateSql = $"update Site set RightValue=(RightValue+2) where RightValue>={entity.LeftValue};update Site set LeftValue=(LeftValue+2) where LeftValue>{entity.LeftValue};";
                    connection.Execute(updateSql, null, trans, 3000, null);
                    //增加站点
                    connection.Execute(sql, propertyContainer.ValuePairs,trans,3000,null);

                    trans.Commit();
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    throw ex;
                }

                isSuccess = true;
            }
            return isSuccess;
        }


        public new bool Delete(int id)
        {
            bool isSuccess = false;

            using (var connection = GetOpenConnection())
            {
                var trans = connection.BeginTransaction();
                try
                {
                    var sql = $"declare @myLeft int;declare @myRight int;declare @myWidth int;" +
                        $"SELECT @myLeft = LeftValue, @myRight = RightValue, @myWidth = (RightValue - LeftValue + 1) FROM[Site] WHERE Id ={id};" +
                        $"DELETE FROM Site WHERE LeftValue BETWEEN @myLeft AND @myRight;" +
                        $"UPDATE[Site] SET RightValue = RightValue - @myWidth WHERE RightValue > @myRight;" +
                        $"UPDATE[Site] SET LeftValue = LeftValue - @myWidth WHERE LeftValue > @myRight; ";
                    connection.Execute(sql, null, trans, 3000, null);
                    trans.Commit();
                    isSuccess = true;
                }
                catch (Exception ex)
                {
                    trans.Rollback();
                    throw ex;
                }

                isSuccess = true;
            }
            return isSuccess;
        }

        public IEnumerable<Site> LoadPageList(int startPage, int pageSize, out int rowCount, Func<Site, bool> where, Func<Site, object> order)
        {
            var result = GetAllList();
            if (where != null)
                result = result.Where(where);
            if (order != null)
                result = result.OrderBy(order);
            else
                result = result.OrderBy(m => m.Id);
            rowCount = result.Count();
            return result.Skip((startPage - 1) * pageSize).Take(pageSize);
        }

        public List<Site> GetNoneChildrenSites()
        {
            List<Site> list = null;
            using (var con = GetOpenConnection())
            {
                var sql = "select * from [Site] where id not in (select distinct ParentId from [Site])";
                list = con.Query<Site>(sql, null, null, true, 3000, null).ToList();
            }
                return list;
        }
    }
}
